package com.yunji.order.command.retund;

import com.yunji.common.exception.ServiceException;
import com.yunji.common.utils.Pair;
import com.yunji.order.command.retund.impl.*;
import com.yunji.order.dto.cmd.RefundCommandDTO;
import com.yunji.order.emuns.RefundStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : peter-zhu
 * @date : 2025/3/7 17:42
 * @description : 售后单状态机
 **/
@Service
@Slf4j
public class RefundStateMachine {

    private static final Map<Pair<RefundStatusEnum, RefundStatusEnum>, IRefundCommand> MACHINE_COMMAND = new HashMap<>();

    @Resource
    private RefundCreateCommand refundCreateCommand;

    @Resource
    private RefundPassCommand refundPassCommand;

    @Resource
    private RefundCancelCommand refundCancelCommand;

    @Resource
    private RefundRejectCommand refundRejectCommand;

    @Resource
    private RefundFinishCommand refundFinishCommand;

    @PostConstruct
    public void init() {
        MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.APPLYING, RefundStatusEnum.APPLYING), refundCreateCommand);
        MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.APPLYING, RefundStatusEnum.REJECTED), refundRejectCommand);
        MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.APPLYING, RefundStatusEnum.CANCELED), refundCancelCommand);
        MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.APPLYING, RefundStatusEnum.PASS), refundPassCommand);
        MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.REFUNDING, RefundStatusEnum.REFUNDED), refundFinishCommand);
        //MACHINE_COMMAND.put(new Pair<>(RefundStatusEnum.REFUNDING, RefundStatusEnum.FAILED), refundFailCommand);
    }

    public static Object statusChange(RefundCommandDTO cmd) {
        IRefundCommand<RefundCommandDTO, ?> machine = MACHINE_COMMAND.get(new Pair<>(cmd.getOldStatus(), cmd.getNewStatus()));
        if (machine != null)
            return machine.execute(cmd);
        else
            throw new ServiceException(MessageFormat.format("不支持的状态变更: {0}({1}) -> {2}({3}) ",
                    cmd.getOldStatus(), cmd.getOldStatus().getValue(), cmd.getNewStatus(), cmd.getNewStatus().getValue()));
    }
}
